package cn.iocoder.yudao.module.project.controller.admin.kismaterielexwarehouse;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.project.controller.admin.orderdetail.vo.OrderDetailRespVO;
import cn.iocoder.yudao.module.project.dal.dataobject.internalcode.InternalCodeDO;
import cn.iocoder.yudao.module.project.dal.dataobject.internalcoderecycle.InternalCodeRecycleDO;
import cn.iocoder.yudao.module.project.dal.dataobject.kismaterielexwarehousehistory.KisMaterielExWarehouseHistoryDO;
import cn.iocoder.yudao.module.project.dal.dataobject.kismaterielexwarehouserecycle.KisMaterielExWarehouseRecycleDO;
import cn.iocoder.yudao.module.project.dal.dataobject.orderdetail.OrderDetailDO;
import cn.iocoder.yudao.module.project.dal.mysql.internalcode.InternalCodeMapper;
import cn.iocoder.yudao.module.project.dal.mysql.internalcoderecycle.InternalCodeRecycleMapper;
import cn.iocoder.yudao.module.project.dal.mysql.kismaterielexwarehouse.KisMaterielExWarehouseMapper;
import cn.iocoder.yudao.module.project.dal.mysql.kismaterielexwarehousehistory.KisMaterielExWarehouseHistoryMapper;
import cn.iocoder.yudao.module.project.dal.mysql.kismaterielexwarehouserecycle.KisMaterielExWarehouseRecycleMapper;
import cn.iocoder.yudao.module.project.dal.mysql.orderdetail.OrderDetailMapper;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.*;
import javax.servlet.http.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.module.project.config.projectDefine.DEFAULT_NUM.DEFAULT_NUM_0;
import static cn.iocoder.yudao.module.project.config.projectDefine.DEFAULT_NUM.DEFAULT_NUM_1;
import static cn.iocoder.yudao.module.project.config.projectDefine.HTTP_STATUS.ERROR_STATUS;
import static cn.iocoder.yudao.module.project.config.projectDefine.MATERIAL_STATUS.*;
import static cn.iocoder.yudao.module.project.config.projectDefine.SUBMIT_STATUS.SUBMIT_STATUS_0;

import cn.iocoder.yudao.module.project.controller.admin.kismaterielexwarehouse.vo.*;
import cn.iocoder.yudao.module.project.dal.dataobject.kismaterielexwarehouse.KisMaterielExWarehouseDO;
import cn.iocoder.yudao.module.project.service.kismaterielexwarehouse.KisMaterielExWarehouseService;

@Tag(name = "管理后台 - 物料出库单")
@RestController
@RequestMapping("/project/kis-materiel-ex-warehouse")
@Validated
@Slf4j
public class KisMaterielExWarehouseController {

    @Resource
    private KisMaterielExWarehouseService kisMaterielExWarehouseService;

    @Resource
    private KisMaterielExWarehouseMapper kisMaterielExWarehouseMapper;

    @Resource
    private OrderDetailMapper orderDetailMapper;

    @Resource
    private InternalCodeMapper internalCodeMapper;

    @Resource
    private InternalCodeRecycleMapper internalCodeRecycleMapper;

    @Resource
    private KisMaterielExWarehouseRecycleMapper kisMaterielExWarehouseRecycleMapper;

    @Resource
    private KisMaterielExWarehouseHistoryMapper kisMaterielExWarehouseHistoryMapper;

    @PostMapping("/create")
    @Operation(summary = "创建物料出库单")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<String> createKisMaterielExWarehouse(@Valid @RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        return success(kisMaterielExWarehouseService.createKisMaterielExWarehouse(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新物料出库单")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:update')")
    public CommonResult<Boolean> updateKisMaterielExWarehouse(@Valid @RequestBody KisMaterielExWarehouseSaveReqVO updateReqVO) {
        kisMaterielExWarehouseService.updateKisMaterielExWarehouse(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除物料出库单")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:delete')")
    public CommonResult<Boolean> deleteKisMaterielExWarehouse(@RequestParam("id") String id) {
        kisMaterielExWarehouseService.deleteKisMaterielExWarehouse(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得物料出库单")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:query')")
    public CommonResult<KisMaterielExWarehouseRespVO> getKisMaterielExWarehouse(@RequestParam("id") String id) {
        KisMaterielExWarehouseDO kisMaterielExWarehouse = kisMaterielExWarehouseService.getKisMaterielExWarehouse(id);
        KisMaterielExWarehouseRespVO kisMaterielExWarehouseRespVO = BeanUtils.toBean(kisMaterielExWarehouse, KisMaterielExWarehouseRespVO.class);
        if (null != kisMaterielExWarehouseRespVO) {
            String orderCode = kisMaterielExWarehouse.getOrderCode();
            String type = kisMaterielExWarehouse.getType();
            String cartonCode = kisMaterielExWarehouseRespVO.getCartonCode();
            String cartonJson = kisMaterielExWarehouseRespVO.getCartonJson();

            // 如果cartonCode为空,则直接返回空
            if (StringUtils.isBlank(cartonCode)) {
                return success(kisMaterielExWarehouseRespVO);
            }

            // 如果cartonJson有数据,就用cartonJson的数据
            if (StringUtils.isNotBlank(cartonJson)) {
                List<CartonCodeDetailNumVO> orderFlexNumVOS = JSONArray.parseArray(cartonJson, CartonCodeDetailNumVO.class);
                kisMaterielExWarehouseRespVO.setCartonCodeNumList(orderFlexNumVOS);

                // 设置箱码合并数量
                if (CollectionUtil.isNotEmpty(orderFlexNumVOS)) {
                    IntSummaryStatistics intSummaryStatistics = orderFlexNumVOS.stream()
                            .mapToInt(CartonCodeDetailNumVO::getNum)
                            .summaryStatistics();
                    int sum = (int) intSummaryStatistics.getSum();
                    kisMaterielExWarehouseRespVO.setCartonCodeNum(sum);
                }
            }

            // // 如果cartonJson没有数据,就用当前订单的同型号其它物料对应的箱码信息
            // if (StringUtils.isBlank(cartonJson)) {
            //     QueryWrapper<KisMaterielExWarehouseDO> queryWrapper = new QueryWrapper<>();
            //     queryWrapper.eq("type", type);
            //     queryWrapper.eq("order_code", orderCode);
            //     List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList(queryWrapper);
            //     kisMaterielExWarehouseDOS = kisMaterielExWarehouseDOS.stream()
            //             .filter(c -> null != c.getCartonCode() && c.getCartonCode().contains(","))
            //             .filter(c -> null != c.getCartonJson())
            //             .collect(Collectors.toList());
            //     // 如果当前订单的其它物料对应的箱码信息有混批箱码,则取这些混批箱码的合计最小值
            //     if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS)) {
            //         List<Integer> numList = new ArrayList<>();
            //         // 计算每个物料的箱码对应的数量合计值
            //         for (KisMaterielExWarehouseDO kisMaterielExWarehouseDO : kisMaterielExWarehouseDOS) {
            //             List<CartonCodeDetailNumVO> cartonCodeDetailNumVOS = JSONArray.parseArray(kisMaterielExWarehouseDO.getCartonJson(), CartonCodeDetailNumVO.class);
            //             if (CollectionUtil.isNotEmpty(cartonCodeDetailNumVOS)) {
            //                 IntSummaryStatistics intSummaryStatistics = cartonCodeDetailNumVOS.stream()
            //                         .mapToInt(CartonCodeDetailNumVO::getNum).summaryStatistics();
            //                 int sum = (int) intSummaryStatistics.getSum();
            //                 numList.add(sum);
            //             }
            //         }
            //         // 每个物料的这些混合箱码的累计合计值放到集合中,取其最小值作为本次物料的数量
            //         if (CollectionUtil.isNotEmpty(numList)) {
            //             IntSummaryStatistics intSummaryStatistics = numList.stream()
            //                     .mapToInt(Integer::intValue).summaryStatistics();
            //             int min = intSummaryStatistics.getMin();
            //             List<CartonCodeDetailNumVO> orderFlexNumVOS = new ArrayList<>();
            //             CartonCodeDetailNumVO cartonCodeDetailNumVO = new CartonCodeDetailNumVO();
            //             cartonCodeDetailNumVO.setId(id);
            //             cartonCodeDetailNumVO.setCartonCode(cartonCode);
            //             cartonCodeDetailNumVO.setNum(min);
            //             orderFlexNumVOS.add(cartonCodeDetailNumVO);
            //             kisMaterielExWarehouseRespVO.setCartonCodeNumList(orderFlexNumVOS);
            //         }
            //     }
            //
            //     // 如果不存在当前订单的其它物料对应的箱码信息有混批箱码,则取当前订单的数量
            //     if (CollectionUtil.isEmpty(kisMaterielExWarehouseDOS)) {
            //         Integer codeNum = kisMaterielExWarehouseRespVO.getCodeNum();
            //         List<CartonCodeDetailNumVO> orderFlexNumVOS = new ArrayList<>();
            //         CartonCodeDetailNumVO cartonCodeDetailNumVO = new CartonCodeDetailNumVO();
            //         cartonCodeDetailNumVO.setId(id);
            //         cartonCodeDetailNumVO.setCartonCode(cartonCode);
            //         cartonCodeDetailNumVO.setNum(codeNum);
            //         orderFlexNumVOS.add(cartonCodeDetailNumVO);
            //         kisMaterielExWarehouseRespVO.setCartonCodeNumList(orderFlexNumVOS);
            //     }
            // }


        }
        return success(kisMaterielExWarehouseRespVO);
    }

    @GetMapping("/page")
    @Operation(summary = "获得物料出库单分页")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:query')")
    public CommonResult<PageResult<KisMaterielExWarehouseRespVO>> getKisMaterielExWarehousePage(@Valid KisMaterielExWarehousePageReqVO pageReqVO) {
        PageResult<KisMaterielExWarehouseDO> pageResult = kisMaterielExWarehouseService.getKisMaterielExWarehousePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, KisMaterielExWarehouseRespVO.class));
    }

    // @GetMapping("/export-excel")
    // @Operation(summary = "导出物料出库单 Excel")
    // // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:export')")
    // @ApiAccessLog(operateType = EXPORT)
    // public void exportKisMaterielExWarehouseExcel(@Valid KisMaterielExWarehousePageReqVO pageReqVO,
    //           HttpServletResponse response) throws IOException {
    //     pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
    //     List<KisMaterielExWarehouseDO> list = kisMaterielExWarehouseService.getKisMaterielExWarehousePage(pageReqVO).getList();
    //     // 导出 Excel
    //     ExcelUtils.write(response, "物料出库单.xls", "数据", KisMaterielExWarehouseRespVO.class,
    //                     BeanUtils.toBean(list, KisMaterielExWarehouseRespVO.class));
    // }




    @PostMapping("/bondCartonCode")
    @Operation(summary = "物料备料单绑定箱码")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<String> bondCartonCode(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        String nickname = SecurityFrameworkUtils.getLoginUserNickname();
        createReqVO.setOperator(nickname);
        // return success(kisMaterielExWarehouseService.bondCartonCode(createReqVO));
        return success(kisMaterielExWarehouseService.bondMultiCartonCode(createReqVO));
    }

    @PostMapping("/bondMultiCartonCode")
    @Operation(summary = "物料备料单绑定多个箱码")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<String> bondMultiCartonCode(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        String nickname = SecurityFrameworkUtils.getLoginUserNickname();
        createReqVO.setOperator(nickname);
        return success(kisMaterielExWarehouseService.bondMultiCartonCode(createReqVO));
    }

    @PostMapping("/bindBoxCodeEdit")
    @Operation(summary = "物料备料单绑定多个箱码")
    public CommonResult<String> bindBoxCodeEdit(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        String nickname = SecurityFrameworkUtils.getLoginUserNickname();
        createReqVO.setOperator(nickname);
        return success(kisMaterielExWarehouseService.bindBoxCodeEdit(createReqVO));
    }

    @GetMapping("/list")
    @Operation(summary = "根据订单编号查询物料信息")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:query')")
    public CommonResult<List<OrderDetailRespVO>> getKisMaterielExWarehouseList(@Valid KisMaterielExWarehousePageReqVO pageReqVO) {
        String orderCode = pageReqVO.getOrderCode();
        QueryWrapper<OrderDetailDO> orderDetailQueryWrapper = new QueryWrapper<>();
        orderDetailQueryWrapper.eq("order_code", orderCode);
        List<OrderDetailDO> orderDetailDOS = orderDetailMapper.selectList(orderDetailQueryWrapper);
        List<OrderDetailRespVO> orderDetailRespVOS = BeanUtils.toBean(orderDetailDOS, OrderDetailRespVO.class);
        // if (CollectionUtil.isNotEmpty(orderDetailRespVOS)) {
        //     QueryWrapper<KisMaterielExWarehouseDO> materielQueryWrapper = new QueryWrapper<>();
        //     materielQueryWrapper.eq("order_code", orderCode);
        //     for (OrderDetailRespVO orderDetailRespVO : orderDetailRespVOS) {
        //         // 型号
        //         String flex = orderDetailRespVO.getFlex();
        //         Long num = orderDetailRespVO.getNum();
        //         materielQueryWrapper.last("and locate(type,'" + flex + "') >0");
        //         List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList(materielQueryWrapper);
        //         if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS) && null != num) {
        //             for (KisMaterielExWarehouseDO kisMaterielExWarehouseDO : kisMaterielExWarehouseDOS) {
        //                 // 箱码
        //                 String cartonCode = kisMaterielExWarehouseDO.getCartonCode();
        //                 for (Long i = 0L; i < num; i++) {
        //
        //                 }
        //             }
        //         }
        //     }
        // }

        return success(orderDetailRespVOS);
    }

    @PostMapping("/materiaPick")
    @Operation(summary = "领料")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<String> materiaPick(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        return success(kisMaterielExWarehouseService.materiaPick(createReqVO));
    }

    @PostMapping("/materiaExamine")
    @Operation(summary = "领料审核")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<Boolean> materiaExamine(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        // QueryWrapper<KisMaterielExWarehouseDO> queryWrapper = new QueryWrapper<>();
        // queryWrapper.eq("order_code", createReqVO.getOrderCode());
        // queryWrapper.eq("type", createReqVO.getType());
        // queryWrapper.eq("code", createReqVO.getCode());
        // List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList(queryWrapper);
        // if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS)) {
        //     KisMaterielExWarehouseDO kisMaterielExWarehouseDO = kisMaterielExWarehouseDOS.get(0);
        //     // kisMaterielExWarehouseDO.setId(createReqVO.getId());
        //     kisMaterielExWarehouseDO.setMaterialStatus(createReqVO.getMaterialStatus());
        //     kisMaterielExWarehouseDO.setMaterialCheck(createReqVO.getMaterialCheck());
        //     kisMaterielExWarehouseDO.setIssuMaterials(createReqVO.getIssuMaterials());
        //     kisMaterielExWarehouseDO.setRemark(createReqVO.getRemark());
        //     kisMaterielExWarehouseDO.setMaterialStatus(MATERIAL_STATUS_1);
        //     kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO);
        // }

        KisMaterielExWarehouseDO kisMaterielExWarehouseDO = new KisMaterielExWarehouseDO();
        kisMaterielExWarehouseDO.setId(createReqVO.getId());
        kisMaterielExWarehouseDO.setMaterialCheck(createReqVO.getMaterialCheck());
        kisMaterielExWarehouseDO.setIssuMaterials(createReqVO.getIssuMaterials());
        kisMaterielExWarehouseDO.setRemark(createReqVO.getRemark());
        kisMaterielExWarehouseDO.setMaterialStatus(MATERIAL_STATUS_1);
        kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO);
        return success(true);
    }

    @PostMapping("/materiaReject")
    @Operation(summary = "领料审核驳回")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<Boolean> materiaReject(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        // QueryWrapper<KisMaterielExWarehouseDO> queryWrapper = new QueryWrapper<>();
        // queryWrapper.eq("order_code", createReqVO.getOrderCode());
        // queryWrapper.eq("type", createReqVO.getType());
        // queryWrapper.eq("code", createReqVO.getCode());
        // List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList(queryWrapper);
        // if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS)) {
        //     KisMaterielExWarehouseDO kisMaterielExWarehouseDO = kisMaterielExWarehouseDOS.get(0);
        //     // kisMaterielExWarehouseDO.setId(createReqVO.getId());
        //     kisMaterielExWarehouseDO.setMaterialStatus(createReqVO.getMaterialStatus());
        //     kisMaterielExWarehouseDO.setMaterialCheck(createReqVO.getMaterialCheck());
        //     kisMaterielExWarehouseDO.setIssuMaterials(createReqVO.getIssuMaterials());
        //     kisMaterielExWarehouseDO.setRemark(createReqVO.getRemark());
        //     kisMaterielExWarehouseDO.setMaterialStatus(MATERIAL_STATUS_0);
        //     kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO);
        // }

        KisMaterielExWarehouseDO kisMaterielExWarehouseDO = new KisMaterielExWarehouseDO();
        kisMaterielExWarehouseDO.setId(createReqVO.getId());
        kisMaterielExWarehouseDO.setMaterialStatus(MATERIAL_STATUS_0);
        // pda提交状态改成未提交
        kisMaterielExWarehouseDO.setSubmitStatus(SUBMIT_STATUS_0);

        kisMaterielExWarehouseDO.setCartonJson("");
        kisMaterielExWarehouseDO.setCartonCode("");

        kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO);
        return success(true);
    }

    @PostMapping("/updateMateria")
    @Operation(summary = "修改物料出库单的审核数量与复核")
    public CommonResult<Boolean> updateMateria(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        KisMaterielExWarehouseDO kisMaterielExWarehouseDO = new KisMaterielExWarehouseDO();
        kisMaterielExWarehouseDO.setId(createReqVO.getId());
        kisMaterielExWarehouseDO.setMaterialCheck(createReqVO.getMaterialCheck());
        kisMaterielExWarehouseDO.setIssuMaterials(createReqVO.getIssuMaterials());
        kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO);
        return success(true);
    }

    @GetMapping("/exportExcel")
    @Operation(summary = "导出物料出库单 Excel")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportKisMaterielExWarehouseExcel(@Valid KisMaterielExWarehousePageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {

        ExcelWriter excelWriter = null;
        String errorMsg = "导出物料出库单错误：";
        String fileName =  "物料出库单" + ".xlsx";
        InputStream inputStream = null;

        try {
            if (StringUtils.isBlank(pageReqVO.getOrderCode())) {
                throw new ServiceException(ERROR_STATUS, "请选择订单编号");
            }

            ClassPathResource classPathResource = new ClassPathResource("/template/领料单导出模板.xlsx");
            inputStream = classPathResource.getInputStream();
            Workbook excel = WorkbookFactory.create(inputStream);

            pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
            List<KisMaterielExWarehouseDO> datas = kisMaterielExWarehouseService.getKisMaterielExWarehousePage(pageReqVO).getList();
            //读取第一个工作表
            Sheet sheet = excel.getSheetAt(0);

            // rowNumber=3表示从第4行开始
            int rowNumber = 3;

            if (null != datas && datas.size() > 0) {
                Row row = sheet.getRow(rowNumber);

                // 创建一个单元格样式，用于设置边框
                CellStyle style = excel.createCellStyle();
                // 设置边框
                style.setBorderTop(BorderStyle.THIN); // 顶部边框
                style.setBorderBottom(BorderStyle.THIN); // 底部边框
                style.setBorderLeft(BorderStyle.THIN); // 左边边框
                style.setBorderRight(BorderStyle.THIN); // 右边边框
                // 设置水平对齐方式
                style.setAlignment(HorizontalAlignment.CENTER);
                // 设置垂直对齐方式
                style.setVerticalAlignment(VerticalAlignment.CENTER);
                style.setWrapText(true); // 设置单元格内容自动换行

                // 先在第4行插入空白行,行数根据datas的大小来确定
                for (KisMaterielExWarehouseDO data : datas) {
                    Row oldRow = sheet.getRow(rowNumber);
                    sheet.shiftRows(rowNumber, sheet.getLastRowNum(), 1);

                    Row newRow = sheet.createRow(rowNumber);
                    if (oldRow != null) {
                        for (int i = 0; i < oldRow.getLastCellNum(); i++) {
                            Cell oldCell = oldRow.getCell(i);
                            Cell newCell = newRow.createCell(i);
                            if (oldCell != null) {
                                newCell.setCellStyle(oldCell.getCellStyle());
                                switch (oldCell.getCellType()) {
                                    case STRING:
                                        newCell.setCellValue(oldCell.getStringCellValue());
                                        break;
                                    case NUMERIC:
                                        newCell.setCellValue(oldCell.getNumericCellValue());
                                        break;
                                    case BOOLEAN:
                                        newCell.setCellValue(oldCell.getBooleanCellValue());
                                        break;
                                    // ... handle other cell types ...
                                }
                            }
                        }
                    }

                    rowNumber++;
                }

                // 设置订单编号
                if (null != pageReqVO.getOrderCode()) {
                    Cell cell = sheet.getRow(1).getCell(0);
                    cell.setCellValue(cell.getStringCellValue() + pageReqVO.getOrderCode());
                    // cell.setCellStyle(style);
                }

                int newRowNumber = 3;
                for (KisMaterielExWarehouseDO data : datas) {
                    String orderCode = data.getOrderCode();
                    String type = data.getType();
                    String racketModel = data.getRacketModel();
                    String sheetNum = data.getSheetNum();
                    String weight = data.getWeight();
                    String cutSize = data.getCutSize();
                    String knivesNum = data.getKnivesNum();
                    String amount = data.getAmount();
                    String materialsCut = data.getMaterialsCut();
                    String addLayers = data.getAddLayers();
                    String materialCheck = data.getMaterialCheck();
                    String issuMaterials = data.getIssuMaterials();
                    String remark = data.getRemark();

                    row = sheet.getRow(newRowNumber++);


                    if (null != type) {
                        Cell cell = row.createCell(1);
                        cell.setCellValue(type);
                        cell.setCellStyle(style);
                    }
                    if (null != racketModel) {
                        Cell cell = row.createCell(3);
                        cell.setCellValue(racketModel);
                        cell.setCellStyle(style);
                    }
                    if (null != sheetNum) {
                        Cell cell = row.createCell(4);
                        cell.setCellValue(sheetNum);
                        cell.setCellStyle(style);
                    }
                    if (null != weight) {
                        Cell cell = row.createCell(5);
                        cell.setCellValue(weight);
                        cell.setCellStyle(style);
                    }
                    if (null != cutSize) {
                        Cell cell = row.createCell(6);
                        cell.setCellValue(cutSize);
                        cell.setCellStyle(style);
                    }
                    if (null != knivesNum) {
                        Cell cell = row.createCell(7);
                        cell.setCellValue(knivesNum);
                        cell.setCellStyle(style);
                    }
                    if (null != amount) {
                        Cell cell = row.createCell(8);
                        cell.setCellValue(amount);
                        cell.setCellStyle(style);
                    }
                    if (null != materialsCut) {
                        Cell cell = row.createCell(9);
                        cell.setCellValue(materialsCut);
                        cell.setCellStyle(style);
                    }
                    if (null != addLayers) {
                        Cell cell = row.createCell(10);
                        cell.setCellValue(addLayers);
                        cell.setCellStyle(style);
                    }
                    if (null != materialCheck) {
                        Cell cell = row.createCell(11);
                        cell.setCellValue(materialCheck);
                        cell.setCellStyle(style);
                    }
                    if (null != issuMaterials) {
                        Cell cell = row.createCell(12);
                        cell.setCellValue(issuMaterials);
                        cell.setCellStyle(style);
                    }
                    if (null != remark) {
                        Cell cell = row.createCell(13);
                        cell.setCellValue(remark);
                        cell.setCellStyle(style);
                    }
                }
            }

            //使用输出流进行表格下载,基于浏览器作为客户端下载
            OutputStream out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel");//代表的是Excel文件类型
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));;//指定以附件形式进行下载
            excel.write(out);
            out.flush();
            out.close();
            excel.close();
        }
        catch (Exception e) {
            log.error(errorMsg, e);
        } finally {
            IoUtil.close(excelWriter);
        }
    }

    @RequestMapping("/exWarehousePage")
    @Operation(summary = "获得物料出库单分页")
    // @PreAuthorize("@ss.hasPermission('project:kis-material-receipt:query')")
    public CommonResult<PageResult<KisMaterialExWarehouseListVO>> getReceiptPage(@Valid @RequestBody KisMaterielExWarehousePageReqVO pageReqVO) {
        Map<String, Object> params = new HashMap<>();
        params.put("pageNo", (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize());
        params.put("pageSize", pageReqVO.getPageSize());

        String orderCode = pageReqVO.getOrderCode();
        if (StringUtils.isNotBlank(orderCode)) {
            params.put("orderCode", orderCode);
        }

        String exCode = pageReqVO.getExCode();
        if (StringUtils.isNotBlank(exCode)) {
            params.put("exCode", exCode);
        }

        String[] dateReq = pageReqVO.getDateReq();
        if (null != dateReq && dateReq.length == 2) {
            String startTime = dateReq[0];
            String endTime = dateReq[1];
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                LocalDate startDate = LocalDate.parse(startTime);
                LocalDate endDate = LocalDate.parse(endTime);
                params.put("startDate", startDate);
                params.put("endDate", endDate);
            }
        }

        List<KisMaterialExWarehouseListVO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseService.selectExCodeByOrderCode(params);
        Long count = kisMaterielExWarehouseService.countExCodeByOrderCode(params);
        PageResult<KisMaterialExWarehouseListVO> result = new PageResult<>();
        result.setList(kisMaterielExWarehouseDOS);
        result.setTotal(count);
        return success(result);

    }

    @GetMapping("/detailByExCode")
    @Operation(summary = "根据物料单号获得物料出库单分页")
    public CommonResult<PageResult<KisMaterielExWarehouseRespVO>> detailByExCode(@Valid KisMaterielExWarehousePageReqVO pageReqVO) {
        PageResult<KisMaterielExWarehouseDO> pageResult = kisMaterielExWarehouseService.detailByExCode(pageReqVO);
        PageResult<KisMaterielExWarehouseRespVO> kisMaterielExWarehouseRespVOPageResult = BeanUtils.toBean(pageResult, KisMaterielExWarehouseRespVO.class);
        List<KisMaterielExWarehouseRespVO> list = kisMaterielExWarehouseRespVOPageResult.getList();
        if (CollectionUtil.isNotEmpty(list)) {
            for (KisMaterielExWarehouseRespVO kisMaterielExWarehouseRespVO : list) {
                String cartonJson = kisMaterielExWarehouseRespVO.getCartonJson();
                // 如果cartonJson有数据,就用cartonJson的数据
                if (StringUtils.isNotBlank(cartonJson)) {
                    List<CartonCodeDetailNumVO> orderFlexNumVOS = JSONArray.parseArray(cartonJson, CartonCodeDetailNumVO.class);
                    kisMaterielExWarehouseRespVO.setCartonCodeNumList(orderFlexNumVOS);

                    // 设置箱码合并数量
                    if (CollectionUtil.isNotEmpty(orderFlexNumVOS)) {
                        IntSummaryStatistics intSummaryStatistics = orderFlexNumVOS.stream()
                                .mapToInt(CartonCodeDetailNumVO::getNum)
                                .summaryStatistics();
                        int sum = (int) intSummaryStatistics.getSum();
                        kisMaterielExWarehouseRespVO.setCartonCodeNum(sum);
                    }
                }
            }
        }
        return success(kisMaterielExWarehouseRespVOPageResult);
    }

    @PostMapping("/queryMultiCartonCode")
    @Operation(summary = "查询物料备料单绑定多个箱码的数量")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<List<CartonCodeDetailNumVO>> queryMultiCartonCode(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        return success(kisMaterielExWarehouseService.queryMultiCartonCode(createReqVO));
    }

    @PostMapping("/updateMultiCartonCode")
    @Operation(summary = "更新物料备料单绑定多个箱码的数量")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<List<CartonCodeDetailNumVO>> updateMultiCartonCode(@RequestBody List<CartonCodeDetailNumVO> reqVO) {
        return success(kisMaterielExWarehouseService.updateMultiCartonCode(reqVO));
    }

    @PostMapping("/bindBoxCodeNumUpdate")
    @Operation(summary = "更新物料备料单绑定多个箱码的数量")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<List<CartonCodeDetailNumVO>> bindBoxCodeNumUpdate(@RequestBody List<CartonCodeDetailNumVO> reqVO) {
        return success(kisMaterielExWarehouseService.bindBoxCodeNumUpdate(reqVO));
    }

    @PostMapping("/submitProductCollect")
    public CommonResult<Boolean> submitProductCollect(@RequestBody List<MaterialProductCollectVO> createReqVOList) {
        return success(kisMaterielExWarehouseService.submitProductCollect(createReqVOList));
    }

    @GetMapping("/clearMultiCartonCode")
    @Operation(summary = "根据物料单id清除箱码")
    public CommonResult<Boolean> clearMultiCartonCode(@RequestParam("id") String id) {
        KisMaterielExWarehouseDO kisMaterielExWarehouseDO = new KisMaterielExWarehouseDO();
        kisMaterielExWarehouseDO.setId(id);
        kisMaterielExWarehouseDO.setCartonCode("");
        kisMaterielExWarehouseDO.setCartonJson("");

        // 清除箱码之后,相应的状态改成未审核状态
        kisMaterielExWarehouseDO.setMaterialStatus(MATERIAL_STATUS_0);
        // pda提交状态改成未提交
        kisMaterielExWarehouseDO.setSubmitStatus(SUBMIT_STATUS_0);
        kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO);
        return success(true);
    }

    // @GetMapping("/exCodeList")
    // @Operation(summary = "根据物料单号获得物料出库单分页")
    // public CommonResult<PageResult<KisMaterielExWarehouseRespVO>> selectExCodeByOrderCode(@Valid KisMaterielExWarehousePageReqVO pageReqVO) {
    //     String orderCode = pageReqVO.getOrderCode();
    //     Map<String, Object> params = new HashMap<>();
    //     params.put("orderCode", orderCode);
    //     List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseService.selectExCodeByOrderCode(params);
    //
    //     Long count = kisMaterielExWarehouseService.countExCodeByOrderCode(params);
    //     PageResult<KisMaterielExWarehouseDO> result = new PageResult<>();
    //     result.setList(kisMaterielExWarehouseDOS);
    //     result.setTotal(count);
    //     return success(BeanUtils.toBean(result, KisMaterielExWarehouseRespVO.class));
    // }

    @PostMapping("/abolish")
    @Operation(summary = "领料单作废")
    // @PreAuthorize("@ss.hasPermission('project:kis-materiel-ex-warehouse:create')")
    public CommonResult<String> abolish(@RequestBody KisMaterielExWarehouseSaveReqVO createReqVO) {
        String exCode = createReqVO.getExCode();
        if (StringUtils.isBlank(exCode)) {
            throw new ServiceException(ERROR_STATUS, "exCode不能为空");
        }

        QueryWrapper<KisMaterielExWarehouseHistoryDO> kisMaterielExWarehouseHistoryDOQueryWrapper = new QueryWrapper<>();
        kisMaterielExWarehouseHistoryDOQueryWrapper.eq("ex_code", exCode);
        List<KisMaterielExWarehouseHistoryDO> kisMaterielExWarehouseHistoryDOS = kisMaterielExWarehouseHistoryMapper.selectList(kisMaterielExWarehouseHistoryDOQueryWrapper);
        if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseHistoryDOS)) {
            for (KisMaterielExWarehouseHistoryDO kisMaterielExWarehouseHistoryDO : kisMaterielExWarehouseHistoryDOS) {
                // kisMaterielExWarehouseHistoryDO.setExNum(DEFAULT_NUM_0);
                kisMaterielExWarehouseHistoryDO.setStatus(DEFAULT_NUM_1);
            }
            kisMaterielExWarehouseHistoryMapper.updateBatch(kisMaterielExWarehouseHistoryDOS);
        }
        if (CollectionUtil.isEmpty(kisMaterielExWarehouseHistoryDOS)) {
            throw new ServiceException(ERROR_STATUS, "exCode:" + exCode + "不用作废");
        }

        QueryWrapper<InternalCodeDO> internalCodeDOQueryWrapper = new QueryWrapper<>();
        internalCodeDOQueryWrapper.eq("ex_code", exCode);
        List<InternalCodeDO> internalCodeDOS = internalCodeMapper.selectList(internalCodeDOQueryWrapper);

        QueryWrapper<KisMaterielExWarehouseDO> warehouseDOQueryWrapper = new QueryWrapper<>();
        warehouseDOQueryWrapper.eq("ex_code", exCode);
        List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList(warehouseDOQueryWrapper);

        if (CollectionUtil.isNotEmpty(internalCodeDOS)) {
            List<InternalCodeRecycleDO> internalCodeRecycleDOS = new ArrayList<>();
            for (InternalCodeDO internalCodeDO : internalCodeDOS) {
                InternalCodeRecycleDO internalCodeRecycleDO = BeanUtils.toBean(internalCodeDO, InternalCodeRecycleDO.class);
                internalCodeRecycleDO.setInternalCodeId(internalCodeDO.getId());
                internalCodeRecycleDOS.add(internalCodeRecycleDO);
            }
            // 内码作废
            internalCodeRecycleMapper.insertBatch(internalCodeRecycleDOS);
            internalCodeMapper.delete(internalCodeDOQueryWrapper);
        }

        if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS)) {
            List<KisMaterielExWarehouseRecycleDO> kisMaterielExWarehouseRecycleDOS = new ArrayList<>();
            for (KisMaterielExWarehouseDO kisMaterielExWarehouseDO : kisMaterielExWarehouseDOS) {
                KisMaterielExWarehouseRecycleDO kisMaterielExWarehouseRecycleDO = BeanUtils.toBean(kisMaterielExWarehouseDO, KisMaterielExWarehouseRecycleDO.class);
                kisMaterielExWarehouseRecycleDO.setExWarehouseId(kisMaterielExWarehouseDO.getId());
                kisMaterielExWarehouseRecycleDOS.add(kisMaterielExWarehouseRecycleDO);
            }
            // 物料出库单作废
            kisMaterielExWarehouseRecycleMapper.insertBatch(kisMaterielExWarehouseRecycleDOS);
            kisMaterielExWarehouseMapper.delete(warehouseDOQueryWrapper);
        }

        return success(null);
    }

}